package com.dragonwu.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.dragonwu.entity.SysMenu;
import com.dragonwu.feign.JwtToken;
import com.dragonwu.feign.OAuth2FeignClient;
import com.dragonwu.model.LoginResult;
import com.dragonwu.service.ISysMenuService;
import com.dragonwu.service.SysLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author DragonWu
 * @since 2022-10-11 8:42
 **/
@Service
public class SysLoginServiceImpl implements SysLoginService {

    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;

    @Value("${basic.token:Basic ZHJhZ29uLWFwaTpkcmFnb24tc2VjcmV0}")
    private String basicToken;

    @Autowired
    private ISysMenuService sysMenuService;

    @Override
    public LoginResult login(String username, String password) throws RuntimeException{
        System.out.println("用户："+username+"开始登录...");
        //1、获取token 远程调用authorization-server 的该服务
        ResponseEntity<JwtToken> tokenResponseEntity = oAuth2FeignClient.getToken("password", username, password, "admin_type", basicToken);
        if(tokenResponseEntity.getStatusCode()!= HttpStatus.OK){
            throw new RuntimeException("token获取失败");
        }
        JwtToken jwtToken=tokenResponseEntity.getBody();
        System.out.println("远程调用授权服务器成功，获取的token为："+ JSON.toJSONString(jwtToken));
        assert jwtToken != null;
        String token=jwtToken.getAccessToken();

        //2、查询我们的菜单数据
        Jwt jwt= JwtHelper.decode(token);//解析jwt
        String jwtJsonStr=jwt.getClaims();//获得解析后的数据
        JSONObject jwtJson=JSON.parseObject(jwtJsonStr);//将解析后的数据转为json格式
        Long userId=Long.valueOf(jwtJson.getString("user_name"));//json中的user_name就是之前登录时存入的用户id

        List<SysMenu> menus=sysMenuService.getMenuByUserId(userId);//通过用户id获取到对应的菜单

        //3、权限数据怎么查询-->不需要查询的，因为我们的jwt里面已包含了
        JSONArray authoritiesJsonArray=jwtJson.getJSONArray("authorities");
        List<SimpleGrantedAuthority> authorities=authoritiesJsonArray.stream()//组装我们的权限数据
                .map(authorityJson->new SimpleGrantedAuthority(authorityJson.toString()))
                .collect(Collectors.toList());

        return new LoginResult(token,menus,authorities);
    }
}
